#ifndef DW_GRAPHICS_OBJECT_H
# define DW_GRAPHICS_OBJECT_H

#	include "boundingvolume.h" 

namespace dw
{
namespace graphics
{

using system::ISerializable;
using system::ISerializer;

using maths::Vector3f;
using maths::Matrix3f;
using maths::Matrix4f;
using maths::Point3f;
using maths::Ray;
using maths::Cuboid;
using maths::Sphere;

class Renderer;
class Modifier;
class Mesh;
class Camera;
class Light;

class Object : public ISerializable
{
public:

	enum Type { UNKNOWN, MESH, CAMERA, LIGHT };

// Constructors
public:
	
	/// Default ctor.
																	Object() {}

	virtual													~Object() {}

// Methods
public:

	virtual Type getType() const ;


	
	/// Get the bounding box of the object.
	const AABBox& getBoundingBox()							const { return _boundingBox; }

	///	Get the normal of the object at the given point.
	virtual Vector3f getNormal(const Point3f& p)	const { return dw::maths::Vector3f(); }



	void setBoundingBox(const AABBox& boundingBox)	{ _boundingBox = boundingBox; }

	void addModifier(Modifier* modifier) { _modifiers.push_back(modifier); }

	void removeModifier(Modifier* modifier) { _modifiers.remove(modifier); }




	virtual bool intersects(const Ray& ray) { return false; }

	virtual void render() { ; }



	Mesh* asMesh();

	Camera* asCamera();

	Light* asLight();



	std::string getSignature() const ;

	void serialize(ISerializer* serializer) const ;

	void deserialize(ISerializer* serializer);

// Fields
protected:

	std::string _materialName;

	/// Bounding box of this object.
	AABBox _boundingBox;

	/// Modifiers applied to this object.
	std::list< Modifier* >						_modifiers;

private:
	
	///	iostream compatible deserialization function.
	friend	
	std::ostream& operator<<(std::ostream& os, const Object& object);
	
	///	iostream compatible deserialization function.
	friend	
	std::istream& operator>>(std::istream& is, Object& object);
};

typedef Object* ObjectPtr;
//typedef system::Pointer< Object >		ObjectPtr;

} // namespace graphics
} // namespace dw	

#endif // !DW_GRAPHICS_OBJECT_H
